home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Classes / WhereAmI / WhereAmI.m < prev    next >
Text File  |  1995-06-12  |  4KB  |  160 lines

  1. /* WhereAmI
  2.  *
  3.  * A category of Application that provides methods for finding the
  4.  * application executable and executable directory.
  5.  *
  6.  * Copyright 1991, 1992 Scott Hess.  This source code may be
  7.  * redistributed and modified without restriction.  Well, one
  8.  * restriction - do not claim that you wrote it.
  9.  *
  10.  * Scott Hess
  11.  * 12901 Upton Avenue South, #326
  12.  * Burnsville, MN  55337
  13.  * (612) 895-1208
  14.  * scott@gac.edu
  15.  * shess@ssesco.com
  16.  */
  17. #import "WhereAmI.h"
  18. #import <appkit/defaults.h>
  19. #import <sys/param.h>
  20. #import <libc.h>
  21. #import <strings.h>
  22.  
  23. @implementation Application (WhereAmI)
  24. int whereAmIReference=0;
  25. -(NXAtom)whoAmI
  26. {
  27.     static NXAtom whoAmI=NULL;
  28.     static BOOL beenHere;
  29.     
  30.     if( !beenHere) {
  31.         char buf[ MAXPATHLEN+1]="";
  32.     char linkbuf[ MAXPATHLEN+1];
  33.     int len, links;
  34.  
  35.     /* First, trace the file that is in NXArgv[ 0].
  36.      * If it starts with '/', it's an absolute pathname and thus truth.
  37.      * Else, check to see if it is relative to the working directory.
  38.      * Else, look on the path for it.
  39.      */
  40.     if( NXArgv[ 0][ 0]=='/') {
  41.         strcpy( buf, NXArgv[ 0]);
  42.     } else if( access( NXArgv[ 0], F_OK)==0) {
  43.         if( getwd( buf)) {
  44.             strcat( buf, "/");
  45.         strcat( buf, NXArgv[ 0]);
  46.         }
  47.     } else {
  48.         const char *pathList=getenv( "PATH");
  49.         if( pathList) {
  50.             while( *pathList) {
  51.             const char *colon=index( pathList, ':');
  52.             if( colon) {
  53.                 strncpy( buf, pathList, colon-pathList);
  54.             buf[ colon-pathList]=0;
  55.             pathList=colon+1;
  56.             } else {
  57.                 strcpy( buf, pathList);
  58.             pathList+=strlen( pathList);
  59.             }
  60.             strcat( buf, "/");
  61.             strcat( buf, NXArgv[ 0]);
  62.             if( access( buf, F_OK)==0) {
  63.                 break;
  64.             }
  65.         }
  66.         }
  67.         if( !pathList || *pathList==0) {
  68.             buf[ 0]='\0';
  69.         }
  70.     }
  71.     
  72.     /* Now, trace the file through symbolic links to where it _really_ is.
  73.      * Note that symbolic links can be multiple.
  74.      * Give up after tracing through 8 links (assume a cycle).
  75.      */
  76.     for( links=0; links<8 && (len=readlink( buf, linkbuf, MAXPATHLEN))!=-1; links++) {
  77.         linkbuf[ len]='\0';
  78.         if( linkbuf[ 0]=='/') {
  79.             strcpy( buf, linkbuf);
  80.         } else {
  81.             char *p=linkbuf;
  82.         for( ;;) {
  83.             char *s=rindex( buf, '/');
  84.             if( s) {
  85.                 *s='\0';
  86.             }
  87.             if( strncmp( p, "../", 3)) {
  88.                 break;
  89.             }
  90.             p+=3;
  91.         }
  92.         strcat( buf, "/");
  93.         strcat( buf, p);
  94.         }
  95.     }
  96.     if( links==8) {
  97.         buf[ 0]='\0';
  98.     }
  99.     
  100.     if( !access( buf, X_OK)) {
  101.         whoAmI=NXUniqueString( buf);
  102.     }
  103.         beenHere=YES;
  104.     }
  105.     return whoAmI;
  106. }
  107. -(NXAtom)whereAmI
  108. {
  109.     static NXAtom whereAmI=NULL;
  110.     static BOOL beenHere=NO;
  111.     
  112.     if( !beenHere) {
  113.     /* Just get the executable path, and then strip off the
  114.      * executable's name.
  115.      */
  116.         NXAtom who=[self whoAmI];
  117.     if( who) {
  118.         char buf[ MAXPATHLEN+1]="";
  119.         char *i;
  120.         strcpy( buf, who);
  121.         i=rindex( buf, '/');
  122.         if( i) {
  123.             *i='\0';
  124.         }
  125.         if( buf[ 0]) {
  126.             whereAmI=NXUniqueString( buf);
  127.         } else {
  128.         whereAmI="";
  129.         }
  130.     }
  131.  
  132.         beenHere=YES;
  133.     }
  134.     return whereAmI;
  135. }
  136. -(const char *)whereIs:(const char *)file path:(char *)result
  137. {
  138.     /* Get the directory the application resides in.
  139.      * Append the file part.
  140.      * Attempt to verify the file's existance.
  141.      */
  142.     if( result) {
  143.     NXAtom where=[self whereAmI];
  144.     if( where) {
  145.         strcpy( result, where);
  146.         strcat( result, "/");
  147.         if( file) {
  148.         strcat( result, file);
  149.         }
  150.         if( !access( result, F_OK)) {
  151.         return result;
  152.         }
  153.         return NULL;
  154.     }
  155.     }
  156.     *result='\0';
  157.     return NULL;
  158. }
  159. @end
  160.